package top.bulk.dbcrypto.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import top.bulk.dbcrypto.util.AnnUtil;
import top.bulk.dbcrypto.util.CryptoUtil;

import java.util.List;

/**
 * 解密拦截器
 *
 * @author 散装java
 * @date 2024-08-01
 */
@Slf4j
@Intercepts({
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})
})
public class BulkDecryptInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object result = invocation.proceed();
        try {
            // 如果是集合
            if (result instanceof List) {
                List<?> list = (List<?>) result;
                if (list.isEmpty()) {
                    return result;
                }
                Class<?> objClazz = list.get(0).getClass();
                if (AnnUtil.hasCrypto(objClazz)) {
                    for (Object item : list) {
                        AnnUtil.doFiled(item, CryptoUtil::aesDecrypt);
                    }
                }
                return result;
            } else {
                AnnUtil.doFiled(result, CryptoUtil::aesDecrypt);

            }
        } catch (Exception e) {
            log.error("DecryptionInterceptor error :{}", e.getMessage(), e);
        }

        return result;
    }
}
